package com.huaxin.hxmoduleworkorder.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huaxin.hxmoduleworkorder.common.annotation.validation.ValidMaintenanceOrderElectricianTaskOperation;
import com.huaxin.hxmoduleworkorder.common.annotation.validation.ValidMaintenanceOrderOperatorRole;
import com.huaxin.hxmoduleworkorder.common.enums.MaintenanceOrderElectricianTaskOperation;
import com.huaxin.hxmoduleworkorder.common.enums.MaintenanceOrderOperatorRole;
import com.huaxin.hxmoduleworkorder.dto.ResponseResult;
import com.huaxin.hxmoduleworkorder.dto.request.*;
import com.huaxin.hxmoduleworkorder.dto.response.MaintenanceOrderElectricianTaskDetailRespDto;
import com.huaxin.hxmoduleworkorder.dto.response.MaintenanceOrderElectricianTaskSummaryRespDto;
import com.huaxin.hxmoduleworkorder.models.MaintenanceOrderElectricianTaskProcess;
import com.huaxin.hxmoduleworkorder.models.MaintenanceOrderElectricianTaskResult;
import com.huaxin.hxmoduleworkorder.service.MaintenanceOrderElectricianTaskProcessService;
import com.huaxin.hxmoduleworkorder.service.MaintenanceOrderElectricianTaskResultService;
import com.huaxin.hxmoduleworkorder.service.MaintenanceOrderElectricianTaskService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Tag(name = "维保工单电工任务", description = "工单电工任务的增删改查及流程操作")
@RestController
@RequiredArgsConstructor
@RequestMapping("/v1/workorder/maintenanceOrderElectrician")
public class MaintenanceOrderElectricianTaskController {

    private final MaintenanceOrderElectricianTaskService service;
    private final MaintenanceOrderElectricianTaskResultService resultService;
    private final MaintenanceOrderElectricianTaskProcessService processService;

    /* *********************************************************************
     * 工单任务基础 CRUD 操作
     ********************************************************************* */

    @Operation(summary = "更新工单任务", description = "仅支持更新电工的负责内容描述")
    @PostMapping("/update")
    public ResponseResult<String> updateTasks(@RequestBody @Valid MaintenanceOrderElectricianTaskUpdateReqDTO in) {
        service.updateTasks(in);
        return ResponseResult.ok("工单任务更新成功");
    }

    /* *********************************************************************
     * 状态与流程管理
     ********************************************************************* */

    @Operation(summary = "获取任务状态", description = "获取任务状态")
    @GetMapping("/getStatus")
    public ResponseResult<String> getOrderStatus(@Parameter(description = "电工任务ID", example = "m_order_001") @RequestParam(value = "id", required = true) String id) {
        return service.getTaskStatus(id);
    }

    @Operation(summary = "获取可执行操作列表", description = "获取电工任务可执行操作列表")
    @GetMapping("/availableOperations")
    public ResponseResult<List<String>> getAvailableOperations(@Parameter(description = "电工任务ID", example = "m_order_001") @RequestParam(value = "id", required = true) String id,
                                                               @Parameter(description = "操作人角色，允许值：customer/admin/electrician", example = "customer") @RequestParam(value = "operatorRole", required = true) @ValidMaintenanceOrderOperatorRole String operatorRole) {
        List<MaintenanceOrderElectricianTaskOperation> operations = service.getAvailableOperations(id, MaintenanceOrderOperatorRole.of(operatorRole));
        List<String> operationCodes = operations.stream().map(MaintenanceOrderElectricianTaskOperation::getCode).toList();
        return ResponseResult.ok(operationCodes);
    }

    @Operation(summary = "检查是否允许执行某操作", description = "检查是否允许执行某操作")
    @GetMapping("/canOperate")
    public ResponseResult<Boolean> canOperate(@Parameter(description = "电工任务ID", example = "m_order_001") @RequestParam(value = "id", required = true) String id,
                                              @Parameter(description = "操作，允许值：accept/reject/on-site/processing/resolve/view", example = "accept") @RequestParam(value = "operation", required = true) @ValidMaintenanceOrderElectricianTaskOperation String operation,
                                              @Parameter(description = "操作人角色，允许值：customer/admin/electrician", example = "customer") @RequestParam(value = "operatorRole", required = true) @ValidMaintenanceOrderOperatorRole String operatorRole) {
        return ResponseResult.ok(service.canOperate(id, MaintenanceOrderElectricianTaskOperation.of(operation), MaintenanceOrderOperatorRole.of(operatorRole)));
    }

    @Operation(summary = "电工接单", description = "电工接单")
    @PostMapping("/accept")
    public ResponseResult<String> accept(@RequestBody @Valid MaintenanceOrderElectricianTaskAcceptReqDto in) {
        return service.accept(in);
    }

    @Operation(summary = "电工标记到场", description = "电工标记到场")
    @PostMapping("/onsite")
    public ResponseResult<String> onsite(@RequestBody @Valid MaintenanceOrderElectricianTaskOnSiteReqDto in) {
        return service.onSite(in);
    }

    @Operation(summary = "电工开始处理", description = "电工开始处理")
    @PostMapping("/startProcess")
    public ResponseResult<String> startProcess(@RequestBody @Valid MaintenanceOrderElectricianTaskProcessingReqDto in) {
        return service.startProcess(in);
    }

    @Operation(summary = "电工提交结果", description = "电工提交结果")
    @PostMapping("/submitResult")
    public ResponseResult<String> submitResult(@RequestBody @Valid MaintenanceOrderElectricianTaskSubmitResultReqDto in) {
        return service.submitResult(in);
    }

    @Operation(summary = "电工完成处理", description = "电工完成处理")
    @PostMapping("/resolve")
    public ResponseResult<String> resolve(@RequestBody @Valid MaintenanceOrderElectricianTaskResolveReqDto in) {
        return service.resolve(in);
    }

    @Operation(summary = "电工拒单", description = "电工拒单")
    @PostMapping("/reject")
    public ResponseResult<String> rejectElectricianTask(@RequestBody @Valid MaintenanceOrderElectricianTaskRejectReqDto in) {
        return service.reject(in);
    }

    /* *********************************************************************
     * 流程记录
     ********************************************************************* */

    @Operation(summary = "获取任务流程历史", description = "获取任务流程历史")
    @GetMapping("/processHistory")
    public ResponseResult<List<MaintenanceOrderElectricianTaskProcess>> getProcessHistory(@Parameter(description = "电工任务ID", example = "m_order_001") @RequestParam(value = "id", required = true) String id) {
        return ResponseResult.ok(processService.getProcessHistory(id));
    }

    /* *********************************************************************
     * 分页与条件查询
     ********************************************************************* */

    @Operation(summary = "分页查询电工任务")
    @PostMapping("/page")
    public ResponseResult<Page<MaintenanceOrderElectricianTaskSummaryRespDto>> pageQuery(@RequestBody @Valid MaintenanceOrderElectricianTaskPageListReqDTO in) {
        return service.pageQuery(in);
    }

    @Operation(summary = "查询某电工的未完成任务")
    @GetMapping("/incomplete")
    public ResponseResult<List<MaintenanceOrderElectricianTaskSummaryRespDto>> getIncompleteTasks(@Parameter(description = "电工ID", required = true) @RequestParam String electricianId) {
        return ResponseResult.ok(service.getIncompleteTasks(electricianId));
    }

    @Operation(summary = "获取电工任务详情", description = "包含任务结果、流程历史")
    @GetMapping("/detail")
    public ResponseResult<MaintenanceOrderElectricianTaskDetailRespDto> detail(@Parameter(description = "电工任务ID", example = "m_order_001") @RequestParam(value = "id", required = true) String id) {
        return ResponseResult.ok(service.detail(id));
    }

    @Operation(summary = "获取电工任务结果")
    @GetMapping("/result")
    public ResponseResult<MaintenanceOrderElectricianTaskResult> result(@Parameter(description = "电工任务ID", example = "m_order_001") @RequestParam(value = "id", required = true) String id) {
        return ResponseResult.ok(resultService.getByElectricianTaskId(id));
    }
}